<template>
  <BasicDrawer
    v-bind="$attrs"
    @register="registerDrawer"
    showFooter
    :title="getTitle"
    width="1000px"
    @ok="handleSubmit"
  >
    <BasicForm @register="registerForm">
      <template #formCode="{ model, field }">
        <FormItemRest>
          <div class="mb-2 flex gap-2 items-center">
            <TreeSelect
              :tree-data="formDataOptions"
              :field-names="{ label: 'name', value: 'code' }"
              treeNodeFilterProp="name"
              show-search
              style="flex: 1"
              v-model:value="model[field]"
              @change="handleFormCodeChange"
            />
            数据源<Select
              v-model:value="dataRef['dbSource']"
              :options="dataSourceDB"
              style="width: 80px"
              @change="handleDbSourceChange"
              show-search
              option-filter-prop="label"
            />
            表<Select
              v-model:value="dataRef['tables']"
              :options="tableDataSource"
              style="width: 120px"
              @change="handleChangeTables"
              show-search
              option-filter-prop="label"
            />
            主键<Select
              v-model:value="dataRef['primaryKey']"
              style="width: 120px"
              :options="fieldsDataOptions"
              show-search
              option-filter-prop="label"
            />
            外键<Input v-model:value="dataRef['foreignKey']" style="width: 120px" />
          </div>
        </FormItemRest>
      </template>
      <template #type_1>
        <FormItemRest>
          <div class="mb-2 flex gap-2 items-center">
            <TimePicker
              value-format="HH:mm:ss"
              v-model:value="dataRef['time']"
              :allow-clear="false"
            />
            每月<InputNumber
              v-model:value="dataRef['month_day']"
              style="width: 100px !important"
            />号
          </div>
        </FormItemRest>
      </template>
      <template #type_2>
        <FormItemRest>
          <div class="mb-2 flex gap-2 items-center">
            <TimePicker
              value-format="HH:mm:ss"
              v-model:value="dataRef['time']"
              :allow-clear="false"
            />
            <CheckboxGroup v-model:value="dataRef['weekDay']" :options="weekDayOptions" />
          </div>
        </FormItemRest>
      </template>
      <template #type_3>
        <FormItemRest>
          <div class="mb-2 flex gap-2 items-center">
            <InputNumber v-model:value="dataRef['interval']" style="width: 100px !important" />
            <RadioGroup
              v-model:value="dataRef['intervalType']"
              style="flex: 1"
              :options="intervalTypeOptions"
            />
          </div>
        </FormItemRest>
      </template>
      <template #mycron="{ model, field }">
        <Input v-model:value="model[field]" />
      </template>

      <template #flowCode="{ model, field }">
        <TreeSelect
          v-model:value="model[field]"
          style="width: 100%"
          :tree-data="flowList"
          :field-names="{ label: 'name', value: 'code' }"
          :show-search="true"
          treeNodeFilterProp="name"
          :treeDefaultExpandAll="true"
          @change="
            (_, names) => {
              model['name'] = names[0];
            }
          "
        />
      </template>
    </BasicForm>
    <div v-if="isShowAceEditor">
      <AceEditor v-model:value="dataRef['data_map']" :readonly="false" style="height: 400px" />
      <div class="flex justify-center gap-10px p-10px">
        <a-button type="primary" @click="handleDesign">设计器</a-button>
        <a-button type="primary" @click="handleRun">运行</a-button>
      </div>
    </div>
    <div v-if="isShowSubscribeTableView">
      <SupscribeTableView
        :stateData="stateData"
        :formCode="dataRef['formCode']"
        :fieldsDataOptions="fieldsDataOptions"
        ref="supscribeTableViewRef"
      />
    </div>
    <DesignIframe ref="ifrmRef" @register="registerDesignIframeView" @success="handleSuccess" />
  </BasicDrawer>
</template>
<script lang="ts">
  import { defineComponent, ref, computed, unref, onUnmounted } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import {
    formSchema,
    setChildren,
    DataType,
    weekDayOptions,
    intervalTypeOptions,
    setData,
    getData,
  } from './dispatchCenter.data';
  import { BasicDrawer, useDrawerInner } from '/@/components/Drawer';
  import {
    getFlowGetDirTreeForScheduler,
    getFlowRunScript,
    getIdeGetDbSources,
    getIdeGetTables,
    getIdeGetTableFields,
  } from '/@/api/flowManage/flowManage';
  import {
    getAdminUpdateJob,
    getAdminCreateJob,
    getAdminListBasicDataOptions,
    getAdminEditJobPage,
  } from '/@/api/system/system';
  import { getFormList } from '/@/api/process/process';
  import { useRouter } from 'vue-router';
  import { getToken } from '/@/utils/auth';
  import {
    Checkbox,
    Select,
    Form,
    TreeSelect,
    TimePicker,
    InputNumber,
    RadioGroup,
    Input,
  } from 'ant-design-vue';
  import { AceEditor } from '/@/components/AceEditor/index';
  import DesignIframe from '/@/views/system/workflow/formManagement/eventDesign/modules/DesignIframe.vue';
  import { useUserStore } from '/@/store/modules/user';
  import { isArray } from '/@/utils/is';
  import SupscribeTableView from './supscribeTableView/SupscribeTableView.vue';
  import { useModal } from '/@/components/Modal';
  import { useMessage } from '/@/hooks/web/useMessage';

  export default defineComponent({
    name: 'DispatchCenterDrawer',
    components: {
      BasicDrawer,
      BasicForm,
      Checkbox,
      CheckboxGroup: Checkbox.Group,
      Select,
      FormItemRest: Form.ItemRest,
      TreeSelect,
      AceEditor,
      TimePicker,
      InputNumber,
      RadioGroup,
      Input,
      DesignIframe,
      SupscribeTableView,
    },
    emits: ['success', 'register'],
    setup(_, { emit }) {
      const userStore = useUserStore();
      const userInfo = userStore.getUserInfo;
      const { createMessage } = useMessage();
      const isUpdate = ref(true);
      const type = ref(DataType.FLOW);
      let dataRef = ref<Recordable>({});
      const stateData = ref<Recordable>({
        basicFields: [],
        fieldMap: {},
      });
      const supscribeTableViewRef = ref<any>(null);
      const [registerForm, { resetFields, setFieldsValue, validate, updateSchema }] = useForm({
        labelWidth: 120,
        schemas: formSchema,
        showActionButtonGroup: false,
      });

      const [registerDrawer, { setDrawerProps, closeDrawer }] = useDrawerInner(async (data) => {
        resetFields();
        setDrawerProps({ confirmLoading: false });
        isUpdate.value = !!data?.isUpdate;
        type.value = data.type;
        console.log('type.value', type.value);
        if (unref(isUpdate)) {
          const res = await getAdminEditJobPage({ id: data.record.id });
          stateData.value.fieldMap = res.fieldMap;
          stateData.value.basicFields = res.basicDataOptions;
          dataRef.value = getData(res, type.value);
          console.log('dataRef.value', dataRef.value);
          setFieldsValue({
            ...dataRef.value,
          });
        } else {
          dataRef.value = {
            time: '12:00:00',
            type: '0',
            job_class: type.value,
          };
        }

        if (type.value === DataType.FLOW) {
          getFlowGetDirTreeAllData();
        } else if (type.value === DataType.SUPSCRIBE) {
          getFormListData();
          getIdeGetDbSourcesData();
          // getAdminListBasicDataOptionsData();
          getTablesData();
          getFieldsData();
        }
        updateSchema([
          {
            field: 'flowCode',
            ifShow: type.value === DataType.FLOW,
          },
        ]);
        updateSchema([
          {
            field: 'formCode',
            ifShow: type.value === DataType.SUPSCRIBE,
          },
        ]);
      });

      const getTitle = computed(() => (!unref(isUpdate) ? '新增' : '编辑'));
      const isShowAceEditor = computed(() => {
        return unref(type) === DataType.SCRIPT;
      });
      const isShowSubscribeTableView = computed(() => {
        return unref(type) === DataType.SUPSCRIBE;
      });

      //获取模块
      const formDataOptions = ref<Recordable[]>([]);
      const getFormListData = async () => {
        formDataOptions.value = [];
        getFormList().then((res) => {
          formDataOptions.value = res || [];
          if (isArray(formDataOptions.value) && formDataOptions.value.length) {
            formDataOptions.value.forEach((item) => {
              item.label = item.name;
              item.value = item.code;
            });
          }
        });
      };

      //获取流程
      const flowList = ref([]);
      const getFlowGetDirTreeAllData = async () => {
        const data = (await getFlowGetDirTreeForScheduler()) || [];
        flowList.value = setChildren(data);
      };
      async function handleSubmit() {
        try {
          const values = await validate();
          let data = Object.assign({}, dataRef.value, values);
          console.log('data', data);
          const { formData, allow, message } = setData(data, type.value);
          if (allow) {
            createMessage.warning(message);
            return;
          }

          let dataMap = {};
          const form: Recordable = { ...formData };
          if (isShowSubscribeTableView.value) {
            const { dataRef } = supscribeTableViewRef.value;
            const { basicFields, dataSource } = dataRef;
            let cleanMap: any = [];
            basicFields.forEach((item) => {
              if (item.checked) {
                let json = {};
                json['fieldName'] = item.fieldName;
                item.options.forEach((it) => {
                  json[it.otherVal] = it.value;
                });
                cleanMap.push(json);
              }
            });
            dataMap['cleanMap'] = cleanMap;

            if (basicFields && basicFields.length) {
              form.basicDataOptions = JSON.stringify(basicFields);
            } else {
              form.basicDataOptions = '';
            }
            if (dataSource && dataSource.length) {
              const obj = {};
              dataSource.forEach((item) => {
                if (item._name) {
                  obj[item.name] = item._name;
                }
              });
              dataMap['fieldMap'] = obj;
            } else {
              dataMap['fieldMap'] = {};
            }
            dataMap['dbSource'] = form.dbSource;
            dataMap['primaryKey'] = form.primaryKey;
            dataMap['foreignKey'] = form.foreignKey;
            dataMap['formCode'] = form.formCode;
            dataMap['table'] = form.tables;
            form.data_map = JSON.stringify(dataMap);
          }

          if (type.value === DataType.FLOW) {
            form.data_map = form.flowCode;
          }

          console.log('form', form);
          setDrawerProps({ confirmLoading: true });
          form.user_name = userInfo.name;
          if (!unref(isUpdate)) {
            await getAdminCreateJob(form);
          } else {
            await getAdminUpdateJob(form);
          }
          closeDrawer();
          emit('success');
        } finally {
          setDrawerProps({ confirmLoading: false });
        }
      }

      const [registerDesignIframeView, { openModal, closeModal }] = useModal();
      //设计器
      const handleDesign = () => {
        openModal(true, {
          scriptStr: unref(dataRef).data_map,
          //   formCode: props.formCode,
        });
      };

      //回调
      const handleSuccess = (value) => {
        console.log('handleSuccess', value);
        if (value) {
          unref(dataRef).data_map = value;
        }
      };
      const ifrmRef = ref<any>(null);
      let ideUrl = 'script_frame.jsp';
      const onMessage = (e) => {
        var d = e.data;
        var data = d.data;
        var type = d.type;
        if (type == 'setScript') {
          console.log('onMessage data', data);
          dataRef.value.data_map = data;
          if (d.cwsToken != null) {
            let cwsToken = d.cwsToken;
            ideUrl = 'script_frame.jsp?cwsToken=' + cwsToken;
          }
          closeModal();
        } else if (type == 'getScript') {
          let serverInfo = userStore.getServerInfo;
          console.log('getScript scriptStr.value=', dataRef.value.data_map);
          let data = {
            type: 'openerScript',
            version: serverInfo.version,
            spVersion: serverInfo.spVersion,
            scene: 'scheduler.script',
            data: dataRef.value.data_map,
          };
          // window.postMessage(data, '*');
          unref(ifrmRef).doPostMessage(data);
        } else if (type == 'setCwsToken') {
          let cwsToken = d.cwsToken;
          ideUrl = 'script_frame.jsp?cwsToken=' + cwsToken;
        }
      };

      if (window.addEventListener) {
        // all browsers except IE before version 9
        window.addEventListener('message', onMessage, false);
      }

      onUnmounted(() => {
        console.log('EventDesign-onUnmounted');
        window.removeEventListener('message', onMessage, false);
      });

      const { resolve } = useRouter();
      const handleRun = async () => {
        const res = await getFlowRunScript({ script: unref(dataRef).data_map });
        let routeUrl: any = {};
        routeUrl = resolve({
          path: '/runScript',
          query: {
            result: res.result,
            token: getToken() as any,
          },
        });
        // + "screenx=" + xposition + ","                       //仅适用于Netscape
        // + "screeny=" + yposition + ","                       //仅适用于Netscape
        // + "left=" + xposition + ","                      //IE
        // + "top=" + yposition;                                //IE
        const height = 400;
        const width = 450;
        const top = (window.screen.height - 30 - height) / 2; //获得窗口的垂直位置;
        // const left = (window.screen.width - 10 - width) / 2; //获得窗口的水平位置;//不生效
        const left = (window.screenX || window.screenLeft || 0) + (screen.width - width) / 2; //获得窗口的水平位置;
        window.open(
          routeUrl.href,
          '',
          `height=${height},width=${width},top=${top}, left=${left},screenx=${left},screeny=${top},alwaysRaised=true,toolbar=no,location=no,resizable=no, scrollbars=yes ,`,
        );
      };

      //form_data
      const handleFormCodeChange = (val) => {
        dataRef.value['formCode'] = val;
        getAdminListBasicDataOptionsData();
      };

      //获取表格数据
      const getAdminListBasicDataOptionsData = async () => {
        if (!dataRef.value['formCode']) {
          return;
        }
        const res = await getAdminListBasicDataOptions({
          formCode: dataRef.value['formCode'],
        });
        stateData.value.fieldMap = {};
        stateData.value.basicFields = [];
        if (res && res.length) {
          stateData.value.basicFields = res.map((item) => {
            if (isArray(item.options) && item.options.length) {
              item.options.forEach((el) => {
                el.otherVal = el.name;
              });
            }
            return item;
          });
        }
      };
      //获取数据源
      const dataSourceDB = ref<Recordable[]>([]);
      const getIdeGetDbSourcesData = () => {
        getIdeGetDbSources()
          .then((res) => {
            dataSourceDB.value = res || [];
            if (isArray(dataSourceDB.value) && dataSourceDB.value.length) {
              dataSourceDB.value.forEach((item) => {
                item.label = item.name;
                item.value = item.name;
              });
            }
          })
          .finally(() => {});
      };

      const handleDbSourceChange = () => {
        dataRef.value.tables = '';
        getTablesData();
      };

      //获取表名
      const tableDataSource = ref<any>([]);
      const getTablesData = async () => {
        try {
          tableDataSource.value = [];
          if (!unref(dataRef).dbSource) return;
          const res = await getIdeGetTables({ dbSource: unref(dataRef).dbSource });
          if (isArray(res)) {
            res.forEach((item) => {
              tableDataSource.value.push({
                label: item,
                value: item,
              });
            });
            if (!unref(isUpdate)) {
              dataRef.value.tables = tableDataSource.value[0].value;
              handleChangeTables();
            }
          }
        } catch (err) {
          console.log('getTablesDta', err);
        }
      };
      //表名change
      const handleChangeTables = () => {
        getFieldsData();
      };
      //获取表对应字段
      const fieldsDataOptions = ref<Recordable[]>([]);
      const getFieldsData = async () => {
        if (!unref(dataRef).tables || !unref(dataRef).dbSource) {
          return;
        }
        try {
          const params = {
            dbSource: unref(dataRef).dbSource,
            table: unref(dataRef).tables,
          };
          fieldsDataOptions.value = [];
          const res = (await getIdeGetTableFields(params)) || [];
          if (isArray(res)) {
            res.forEach((item) => {
              fieldsDataOptions.value.push({
                label: item,
                value: item,
              });
            });
          }
        } catch (err) {
          console.log(err);
        }
      };
      return {
        registerDrawer,
        registerForm,
        getTitle,
        handleSubmit,
        dataRef,
        formDataOptions,
        flowList,
        weekDayOptions,
        intervalTypeOptions,
        isShowAceEditor,
        handleRun,
        handleDesign,
        handleSuccess,
        registerDesignIframeView,
        ifrmRef,
        handleFormCodeChange,
        handleDbSourceChange,
        handleChangeTables,
        tableDataSource,
        dataSourceDB,
        fieldsDataOptions,
        isShowSubscribeTableView,
        stateData,
        supscribeTableViewRef,
      };
    },
  });
</script>
